package cz.cuni.amis.episodic.bayes.experiment;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import smile.Network;
import cz.cuni.amis.episodic.bayes.memories.MemoryCreationStrategy;
import cz.cuni.amis.episodic.bayes.utils.DynamicNodeProperty;
import cz.cuni.amis.episodic.bayes.utils.MemoryChartCreator;
import cz.cuni.amis.episodic.bayes.utils.chart.GraphPaintingDevice;
import cz.cuni.amis.episodic.bayes.utils.chart.PngGraphDevice;
import cz.cuni.amis.episodic.dybanem.DBN;
import cz.cuni.amis.episodic.lisp.DefaultLispTranslator;
import cz.cuni.amis.episodic.lisp.LispPlanResourceCreator;
import cz.cuni.amis.episodic.lisp.LispPlanToCsvData.LispToCsvResult;
import cz.cuni.amis.episodic.lisp.behan.LispTree;
import cz.cuni.amis.episodic.lisp.visitor.TreeTraceVisitor;

/**
 * Monroe corpus experiments.
 *
 * @author ik
 */
public class Experiment_4_monroe {

    public static void main(String[] args) throws FileNotFoundException, IOException, Exception {
    	String lispPlan = "src/main/resources/monroe/monroe-small.txt";
        File experimentDir = new File("target/experiments/4_monroe/");
    	LispPlanResourceCreator.processCorpus(lispPlan,
                new File("../datasets/4_monroe/"),
                3);

       
        //MemoryCreator memoryCreator = new IntervalSurpriseMemoryCreator(graphDevice);
        //MemoryCreator memoryCreator = new MinimizeKLMemoryCreator(graphDevice);
        //RetrospectiveMemoriesCreator.createMemories(net, evidence, targets, 5,  memoryCreator);//new MinimizeKLMemoryCreator()); 
        
        testArchitecture(experimentDir, 
        		"../example_networks/4_monroe/monroe-small_hhmm.xdsl", 
        		lispPlan);
        testArchitecture(experimentDir, 
        		"../example_networks/4_monroe/monroe-small_chmm.xdsl", 
        		lispPlan);
    }
    
    public static void testArchitecture(File experimentRootDir, String networkFilename, String evidencePlanFilename) throws Exception {
        File networkFile = new File(networkFilename);
    	String experimentName = networkFile.getName().split("\\.")[0];
    	
    	File experimentSubDir = new File(experimentRootDir, experimentName);
    	// create root dir for this subexperiment
    	experimentSubDir.mkdirs();
    	
    	Network origNet = new Network();
        origNet.readFile(networkFilename);

        List<String> evidence = readEvidence(evidencePlanFilename);//Arrays.asList("NAVEGATE_VEHICLE_a", "CLIMB_IN_a", "NAVEGATE_VEHICLE_a", "CLIMB_OUT_a", "HOOK_TO_TOW_TRUCK_a", "PLACE_CONES_a", "UNHOOK_FROM_TOW_TRUCK_a");
        evidence = evidence.subList(0, 10);
        
        DBN net = new DBN(origNet, evidence.size() + 5);

        String[] targets = new String[]{"O", "G1", "G2"};
        List<DynamicNodeProperty[]> res = Experiment_2.evolveOverTime(net, "O", evidence, targets);

        // draw default graphs 
        File graphsDir = new File(experimentSubDir, "graphs");
        graphsDir.mkdirs();
        GraphPaintingDevice graphDevice = new PngGraphDevice(graphsDir);
        MemoryChartCreator.createDefaultCharts(res, net, graphDevice);

        MemoryCreationStrategy.compare(evidence, net, targets, graphDevice);      
    }
    
    public static List<String> readEvidence(String inputLispPlan) {
    	LispTree parser = new LispTree(inputLispPlan);
		LispToCsvResult res = new LispToCsvResult();

		final List<String> evidence = new LinkedList<>();
		
		parser.walkInForest(new TreeTraceVisitor() {

			@Override
			public void traceVisited(List<List<String>> trace) {
				String atomicAction = trace.get(trace.size()-1).get(0);
				evidence.add(DefaultLispTranslator.translateOutcome(atomicAction));
				/*List<String> episTrace = new ArrayList<>();
				for (List<String> elem : trace) {
					episTrace.add(elem.get(0));
				}
				System.out.println(StringUtils.join(episTrace, " -> "));
				*/
			}
			
		});
		return evidence;
    }
}
